package com.pxst.merchant.service.impl;

import cn.afterturn.easypoi.excel.entity.ExportParams;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.pxst.agent.entity.SysAgents;
import com.pxst.agent.mapper.SysAgentsMapper;
import com.pxst.internalReports.entity.DailBalanceEntity;
import com.pxst.internalReports.resp.DailBalanceSearchResp;
import com.pxst.internalReports.resp.VirtualBankStatementExcelResp;
import com.pxst.merchant.entity.SysMerchantIncomeStatistics;
import com.pxst.merchant.entity.SysMerchantInfo;
import com.pxst.merchant.mapper.SysMerchantIncomeStatisticsMapper;
import com.pxst.merchant.req.MerchantDailyReportReq;
import com.pxst.merchant.req.MerchantSummaryReportReq;
import com.pxst.merchant.resp.MerchantDailyReportResp;
import com.pxst.merchant.resp.MerchantSummaryReportResp;
import com.pxst.merchant.service.SysMerchantIncomeStatisticsService;
import com.pxst.resp.ApiResp;
import com.pxst.utils.ExcelUtils;
import icu.mhb.mybatisplus.plugln.base.service.impl.JoinServiceImpl;
import icu.mhb.mybatisplus.plugln.core.JoinLambdaWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zarke
 * @since 2023-09-18 15:17:46
 */
@Service
@Transactional
@Slf4j
public class SysMerchantIncomeStatisticsServiceImpl extends JoinServiceImpl<SysMerchantIncomeStatisticsMapper, SysMerchantIncomeStatistics> implements SysMerchantIncomeStatisticsService {

    @Autowired
    private SysMerchantIncomeStatisticsMapper sysMerchantIncomeStatisticsMapper;

    @Autowired
    private SysAgentsMapper sysAgentsMapper;


    /**
     * 每日报表-搜索
     *
     * @param merchantIncomeReq
     * @return
     */
    @Override
    public ApiResp<MerchantDailyReportResp> getDailyReport(MerchantDailyReportReq merchantIncomeReq) {

        JoinLambdaWrapper<SysMerchantIncomeStatistics> jlw = new JoinLambdaWrapper<>(SysMerchantIncomeStatistics.class);
        //给月调整表添加查询条件
        jlw.in(merchantIncomeReq.getMerchantId() != null && merchantIncomeReq.getMerchantId().size() > 0,
                        SysMerchantIncomeStatistics::getMerchantId, merchantIncomeReq.getMerchantId())
                .between(merchantIncomeReq.getStartDate() != null && merchantIncomeReq.getEndDate() != null,
                        SysMerchantIncomeStatistics::getDate, merchantIncomeReq.getStartDate(), merchantIncomeReq.getEndDate());
        //关联商户信息表，并添加商户条件
        jlw.leftJoin(SysMerchantInfo.class, SysMerchantInfo::getId, SysMerchantIncomeStatistics::getMerchantId)
                .eq(StringUtils.hasText(merchantIncomeReq.getCurrency()), SysMerchantInfo::getCurrency, merchantIncomeReq.getCurrency())
                .in(merchantIncomeReq.getAgentId() != null && merchantIncomeReq.getAgentId().size() > 0,
                        SysMerchantInfo::getAgentId, merchantIncomeReq.getAgentId())
                .end();
        //商户关联代理表，查询总代和代理的条件，若无选择代理，显示结果为总代与代理加总后之数值。
        jlw.leftJoin(SysAgents.class, SysAgents::getId, SysMerchantInfo::getAgentId)
                .eq(merchantIncomeReq.getBelongId() != null, SysAgents::getBelongId, merchantIncomeReq.getBelongId())
                .or()
                .eq(merchantIncomeReq.getBelongId() != null, SysAgents::getId, merchantIncomeReq.getBelongId())
                .end();
        //选择返回的参数，并按照日期分组求和，降序排序
        jlw.selectAs((cb) -> {
                    cb.add(SysMerchantIncomeStatistics::getDate)
                            .add("sum(sys_merchant_income_statistics.fi_bank_markup_rate)", "fiBankMarkupRate", false)
                            .add("sum(sys_merchant_income_statistics.fi_qrpay_markup_rate)", "fiQrpayMarkupRate", false)
                            .add("sum(sys_merchant_income_statistics.fo_markup_rate)", "foMarkupRate", false)
                            .add("sum(sys_merchant_income_statistics.fi_bank_fees)", "fiBankFees", false)
                            .add("sum(sys_merchant_income_statistics.fo_fees)", "foFees", false)
                            .add("sum(sys_merchant_income_statistics.fi_qrpay_fees)", "fiQrpayFees", false);
                })
                .orderByAsc(SysMerchantIncomeStatistics::getDate)
                .groupBy(SysMerchantIncomeStatistics::getDate);
        PageHelper.startPage(merchantIncomeReq.getPage(), merchantIncomeReq.getRp());
        Page<MerchantDailyReportResp> merchantIncomeRespPage = (Page<MerchantDailyReportResp>) sysMerchantIncomeStatisticsMapper.joinSelectList(jlw, MerchantDailyReportResp.class);
        List<MerchantDailyReportResp> merchantIncomeResps = merchantIncomeRespPage.getResult();
        if (merchantIncomeResps.size() <= 0) {
            return ApiResp.sucess(new MerchantDailyReportResp());
        }
        //计算每条数据的总抽成
        List<MerchantDailyReportResp> collect = merchantIncomeResps.stream().map(iter -> {
            iter.setSumRate(iter.getFoMarkupRate().add(iter.getFiBankMarkupRate().add(iter.getFiQrpayMarkupRate())));
            return iter;
        }).collect(Collectors.toList());
        return ApiResp.page(merchantIncomeReq.getPage(), merchantIncomeReq.getRp(), (int) merchantIncomeRespPage.getTotal(), collect);
    }

    /**
     * 代理收入总表-搜索
     *
     * @param merchantIncomeReq
     * @return
     */
    @Override
    public ApiResp<MerchantSummaryReportResp> getSummaryReport(MerchantSummaryReportReq merchantIncomeReq) {
        String startDate = merchantIncomeReq.getYear().toString() + "-" + merchantIncomeReq.getMonth().toString() + "-01";
        String endDate = merchantIncomeReq.getYear().toString() + "-" + merchantIncomeReq.getMonth().toString() + "-31";
        JoinLambdaWrapper<SysMerchantIncomeStatistics> jlw = new JoinLambdaWrapper<>(SysMerchantIncomeStatistics.class);

        jlw.between(SysMerchantIncomeStatistics::getDate, startDate, endDate)
                .in(merchantIncomeReq.getMerchantId() != null && merchantIncomeReq.getMerchantId().size() > 0,
                        SysMerchantIncomeStatistics::getMerchantId, merchantIncomeReq.getMerchantId())
                .selectAs((cb) -> {
                    cb.add("sum(fi_bank_markup_rate+fi_qrpay_markup_rate+fi_truewallet_markup_rate+fo_markup_rate)", "markup", false)
                            .add("sum(fi_truewallet_rebate+fo_bank_rebate+fo_qrpay_rebate+fo_rebate)", "rebate", false)
                            .add("sum(aj_credit-aj_debit)", "monthlyAdjustment", false)
                            .add("sum(fi_bank_markup_rate+fi_qrpay_markup_rate+fi_truewallet_markup_rate+fo_markup_rate+" +
                                    "fi_truewallet_rebate+fo_bank_rebate+fo_qrpay_rebate+fo_rebate+aj_credit-aj_debit)", "total", false)
                            .add("sum(fi_bank_balance)", "fiBankBalance", false)
                            .add("sum(fi_qrpay_balance)", "fiQrpayBalance", false)
                            .add("sum(fo_balance)", "foBalance", false)
                            .add("sum(fi_bank_fees+fi_qrpay_fees+fi_truewallet_fees+fx_fees+fo_fees)", "totalFee", false);

                })
                .groupBy(SysMerchantIncomeStatistics::getMerchantId);
        //关联商户信息表
        jlw.leftJoin(SysMerchantInfo.class, SysMerchantInfo::getId, SysMerchantIncomeStatistics::getMerchantId)
                .eq(StringUtils.hasText(merchantIncomeReq.getCurrency()), SysMerchantInfo::getCurrency, merchantIncomeReq.getCurrency())
                .in(merchantIncomeReq.getAgentId() != null && merchantIncomeReq.getAgentId().size() > 0,
                        SysMerchantInfo::getAgentId, merchantIncomeReq.getAgentId())
                .selectAs((cb) -> {
                    cb.addFunAlias(SysMerchantInfo::getName, MerchantSummaryReportResp::getMerchantName)
                            .addFunAlias(SysMerchantInfo::getCode, MerchantSummaryReportResp::getMerchantCode)
                            .add(SysMerchantInfo::getCurrency);
                })
                .end();
        //关联代理信息表
        jlw.leftJoin(SysAgents.class, SysAgents::getId, SysMerchantInfo::getAgentId)
                .eq(merchantIncomeReq.getBelongId() != null, SysAgents::getBelongId, merchantIncomeReq.getBelongId())
                .or()
                .eq(merchantIncomeReq.getBelongId() != null, SysAgents::getId, merchantIncomeReq.getBelongId())
                .selectAs((cb) -> {
                    cb.add(SysAgents::getId)
                            .add(SysAgents::getDisplayId)
                            .addFunAlias(SysAgents::getFullName, MerchantSummaryReportResp::getAgentName);
                })
                .orderByAsc(SysAgents::getId)
                .groupBy(SysAgents::getId)
                .end();

        PageHelper.startPage(merchantIncomeReq.getPage(), merchantIncomeReq.getRp());
        Page<MerchantSummaryReportResp> page = (Page<MerchantSummaryReportResp>) sysMerchantIncomeStatisticsMapper.joinSelectList(jlw, MerchantSummaryReportResp.class);
        if (page.getTotal() > 0) {
            if (page.getTotal() <= page.getPageSize()) {
                //查询的数量只够一页展示，那么小计和总计都相等
                //将数据进行处理，给返回类加上上级代理属性
                List<MerchantSummaryReportResp> collect = addAgent(page.getResult());
                //获取小计数据
                Map<String, BigDecimal> subTotals = getSubTotals(collect);
                //获取总计数据
                Map<String, BigDecimal> totals = getSubTotals(collect);
                return ApiResp.page(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), collect, subTotals, totals);
            } else {
                //查询的数量超过一页展示，那么小计和总计分开计算
                //将数据进行处理，给返回类加上上级代理属性
                List<MerchantSummaryReportResp> collect = addAgent(page.getResult());
                //获取小计数据
                Map<String, BigDecimal> subTotals = getSubTotals(collect);
                //获取总计数据
                Map<String, BigDecimal> totals = getSummaryReportList(merchantIncomeReq);
                return ApiResp.page(page.getPageNum(), page.getPageSize(), (int) page.getTotal(), collect, subTotals, totals);
            }
        }
        //创建空小计总计
        Map<String, BigDecimal> subTotals = getNotSubTotals();
        Map<String, BigDecimal> totals = getNotSubTotals();
        return ApiResp.page(page, subTotals, totals);
    }


    //创建空小计总计
    private Map<String, BigDecimal> getNotSubTotals() {
        BigDecimal markup = new BigDecimal(0);
        BigDecimal rebate = new BigDecimal(0);
        BigDecimal monthlyAdjustment = new BigDecimal(0);
        BigDecimal total = new BigDecimal(0);

        Map<String, BigDecimal> subTotal = new HashMap<>();
        subTotal.put("markup", markup);
        subTotal.put("rebate", rebate);
        subTotal.put("monthlyAdjustment", monthlyAdjustment);
        subTotal.put("total", total);
        return subTotal;
    }

    //获取总计数据
    private Map<String, BigDecimal> getSummaryReportList(MerchantSummaryReportReq merchantIncomeReq) {
        String startDate = merchantIncomeReq.getYear().toString() + "-" + merchantIncomeReq.getMonth().toString() + "-01";
        String endDate = merchantIncomeReq.getYear().toString() + "-" + merchantIncomeReq.getMonth().toString() + "-31";
        JoinLambdaWrapper<SysMerchantIncomeStatistics> jlw = new JoinLambdaWrapper<>(SysMerchantIncomeStatistics.class);

        jlw.between(SysMerchantIncomeStatistics::getDate, startDate, endDate)
                .in(merchantIncomeReq.getMerchantId() != null && merchantIncomeReq.getMerchantId().size() > 0,
                        SysMerchantIncomeStatistics::getMerchantId, merchantIncomeReq.getMerchantId())
                .selectAs((cb) -> {
                    cb.add("sum(fi_bank_markup_rate+fi_qrpay_markup_rate+fi_truewallet_markup_rate+fo_markup_rate)", "markup", false)
                            .add("sum(fi_truewallet_rebate+fo_bank_rebate+fo_qrpay_rebate+fo_rebate)", "rebate", false)
                            .add("sum(aj_credit-aj_debit)", "monthlyAdjustment", false)
                            .add("sum(fi_bank_markup_rate+fi_qrpay_markup_rate+fi_truewallet_markup_rate+fo_markup_rate+" +
                                    "fi_truewallet_rebate+fo_bank_rebate+fo_qrpay_rebate+fo_rebate+aj_credit-aj_debit)", "total", false);
                });
        //关联商户信息表
        jlw.leftJoin(SysMerchantInfo.class, SysMerchantInfo::getId, SysMerchantIncomeStatistics::getMerchantId)
                .eq(StringUtils.hasText(merchantIncomeReq.getCurrency()), SysMerchantInfo::getCurrency, merchantIncomeReq.getCurrency())
                .in(merchantIncomeReq.getAgentId() != null && merchantIncomeReq.getAgentId().size() > 0,
                        SysMerchantInfo::getAgentId, merchantIncomeReq.getAgentId())
                .end();
        //关联代理信息表
        jlw.leftJoin(SysAgents.class, SysAgents::getId, SysMerchantInfo::getAgentId)
                .eq(merchantIncomeReq.getBelongId() != null, SysAgents::getBelongId, merchantIncomeReq.getBelongId())
                .or()
                .eq(merchantIncomeReq.getBelongId() != null, SysAgents::getId, merchantIncomeReq.getBelongId())
                .end();

        List<Map> maps = sysMerchantIncomeStatisticsMapper.joinSelectList(jlw, Map.class);
        Map<String, BigDecimal> map = maps.get(0);
        return map;
    }

    //获取小计数据
    private Map<String, BigDecimal> getSubTotals(List<MerchantSummaryReportResp> collect) {
        BigDecimal markup = new BigDecimal(0);
        BigDecimal rebate = new BigDecimal(0);
        BigDecimal monthlyAdjustment = new BigDecimal(0);
        BigDecimal total = new BigDecimal(0);

        for (MerchantSummaryReportResp reportResp : collect) {
            markup = markup.add(reportResp.getMarkup());
            rebate = rebate.add(reportResp.getRebate());
            monthlyAdjustment = monthlyAdjustment.add(reportResp.getMonthlyAdjustment());
            total = total.add(reportResp.getTotal());
        }

        Map<String, BigDecimal> subTotal = new HashMap<>();
        subTotal.put("markup", markup);
        subTotal.put("rebate", rebate);
        subTotal.put("monthlyAdjustment", monthlyAdjustment);
        subTotal.put("total", total);
        return subTotal;
    }

    //将数据进行处理，给返回类加上上级代理属性
    private List<MerchantSummaryReportResp> addAgent(List<MerchantSummaryReportResp> merchantSummaryReportResps) {
        List<MerchantSummaryReportResp> collect = merchantSummaryReportResps.stream().map(iter -> {
            SysAgents sysAgents = sysAgentsMapper.selectById(iter.getId());
            if (sysAgents.getBelongId() != null) {
                SysAgents topSysAgents = sysAgentsMapper.selectById(sysAgents.getBelongId());
                iter.setTopAgentId(topSysAgents.getDisplayId());
                iter.setTopAgentName(topSysAgents.getFullName());
            } else {
                iter.setTopAgentId(sysAgents.getDisplayId());
                iter.setTopAgentName(sysAgents.getFullName());
            }
            return iter;
        }).collect(Collectors.toList());
        return collect;
    }


    @Override
    public DailBalanceSearchResp searchDailyBalance(Integer year, Integer month, String currency, List<Long> merchantId) {
        DailBalanceSearchResp resp = new DailBalanceSearchResp();

        resp.getTotals().setFiBankBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiArPayBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiTruewalletBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFoBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFoBankFeeMerchant(BigDecimal.valueOf(0));
        resp.getTotals().setFoEightPayAutoWithdrawalBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFoQijiPayWithdrawalBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFoDaPayWithdrawalBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFoH1PayWithdrawalBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFoYouktPayWithdrawalBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFxBalance(BigDecimal.valueOf(0));
        resp.getTotals().setAjDebit(BigDecimal.valueOf(0));
        resp.getTotals().setAjCredit(BigDecimal.valueOf(0));
        resp.getTotals().setFiVnPayZaloQrBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiVnPayMomoQrBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiVnPayViettelQrBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiVnPayViettelFixBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiVnPayBankQrBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiVnPayBankBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiVnPayBankCardBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiVnPayRcgCardPcBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiVnPayRcgCardZingBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiDaPayZfbYhkBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiDaPayNetGateBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiDaPayBank2BankBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiH1PayUnionPayBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFiYouKtPayBank2BankBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFxDaPayBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFxVnPayBalance(BigDecimal.valueOf(0));
        resp.getTotals().setFxH1PayBalance(BigDecimal.valueOf(0));

        JoinLambdaWrapper<SysMerchantIncomeStatistics> jlw = new JoinLambdaWrapper(SysMerchantIncomeStatistics.class);

        jlw
                .likeRight(!ObjectUtils.isEmpty(year) && !ObjectUtils.isEmpty(month), SysMerchantIncomeStatistics::getDate, String.valueOf(year) + "-" + String.valueOf(month))
                .in(!ObjectUtils.isEmpty(merchantId), SysMerchantIncomeStatistics::getMerchantId, merchantId)
                .groupBy(SysMerchantIncomeStatistics::getDate)
                .orderByAsc(SysMerchantIncomeStatistics::getDate)
                .selectAs(smis -> {
                    smis.addFunAlias(SysMerchantIncomeStatistics::getDate, DailBalanceEntity::getDate);
                    smis.add("sum(fi_bank_balance)", "fiBankBalance", false);
                    smis.add("sum(fi_qrpay_balance)", "fiArPayBalance", false);
                    smis.add("sum(fi_truewallet_balance)", "fiTruewalletBalance", false);
                    smis.add("sum(fo_balance)", "foBalance", false);
                    smis.add("sum(fo_bank_fee_merchant)", "foBankFeeMerchant", false);
                    smis.add("sum(fo_eightPay_auto_withdrawal_balance)", "foEightPayAutoWithdrawalBalance", false);
                    smis.add("sum(fo_qijiPay_withdrawal_balance)", "foQijiPayWithdrawalBalance", false);
                    smis.add("sum(fo_dapay_withdrawal_balance)", "foDaPayWithdrawalBalance", false);
                    smis.add("sum(fo_h1pay_withdrawal_balance)", "foH1PayWithdrawalBalance", false);
                    smis.add("sum(fo_youktpay_withdrawal_balance)", "foYouktPayWithdrawalBalance", false);
                    smis.add("sum(fx_balance)", "fxBalance", false);
                    smis.add("sum(aj_debit)", "ajDebit", false);
                    smis.add("sum(aj_credit)", "ajCredit", false);
                    smis.add("sum(fi_vnpay_zalo_qr_balance)", "fiVnPayZaloQrBalance", false);
                    smis.add("sum(fi_vnpay_momo_qr_balance)", "fiVnPayMomoQrBalance", false);
                    smis.add("sum(fi_vnpay_viettel_qr_balance)", "fiVnPayViettelQrBalance", false);
                    smis.add("sum(fi_vnpay_viettel_fix_balance)", "fiVnPayViettelFixBalance", false);
                    smis.add("sum(fi_vnpay_bank_qr_balance)", "fiVnPayBankQrBalance", false);
                    smis.add("sum(fi_vnpay_bank_balance)", "fiVnPayBankBalance", false);
                    smis.add("sum(fi_vnpay_bank_card_balance)", "fiVnPayBankCardBalance", false);
                    smis.add("sum(fi_vnpay_rcgcag_pc_balance)", "fiVnPayRcgCardPcBalance", false);
                    smis.add("sum(fi_vnpay_rcgcag_zing_balance)", "fiVnPayRcgCardZingBalance", false);
                    smis.add("sum(fi_dapay_zfbyhk_balance)", "fiDaPayZfbYhkBalance", false);
                    smis.add("sum(fi_dapay_netgate_balance)", "fiDaPayNetGateBalance", false);
                    smis.add("sum(fi_dapay_bank2bank_balance)", "fiDaPayBank2BankBalance", false);
                    smis.add("sum(fi_h1pay_union_pay_balance)", "fiH1PayUnionPayBalance", false);
                    smis.add("sum(fi_youktpay_bank2bank_balance)", "fiYouKtPayBank2BankBalance", false);
                    smis.add("sum(fx_vnpay_balance)", "fxVnPayBalance", false);
                    smis.add("sum(fx_dapay_balance)", "fxDaPayBalance", false);
                    smis.add("sum(fx_h1pay_balance)", "fxH1PayBalance", false);
                    smis.add("sum(fi_bank_fees)", "fiBankFees", false);
                    smis.add("sum(fi_qrpay_fees)", "fiQrQayFees", false);
                    smis.add("sum(fi_truewallet_fees)", "fiTrueWalletFees", false);
                    smis.add("sum(fo_fees)", "foFees", false);
                    smis.add("sum(fo_eightPay_auto_withdrawal_fees)", "foEightPayAutoWithdrawalFees", false);
                    smis.add("sum(fo_qijiPay_withdrawal_fees)", "foQiJiPayWithdrawalFees", false);
                    smis.add("sum(fo_dapay_withdrawal_fees)", "foDaPayWithdrawalFees", false);
                    smis.add("sum(fx_fees)", "fxFees", false);
                    smis.add("sum(fi_vnpay_zalo_qr_fees)", "fiVnPayZaLoQrFees", false);
                    smis.add("sum(fi_vnpay_momo_qr_fees)", "fiVnPayMomoQrFees", false);
                    smis.add("sum(fi_vnpay_viettel_qr_fees)", "fiVnPayViettelQrFees", false);
                    smis.add("sum(fi_vnpay_viettel_fix_fees)", "fiVnPayViettelFixFees", false);
                    smis.add("sum(fi_vnpay_bank_qr_fees)", "fiVnPayBankQrFees", false);
                    smis.add("sum(fi_vnpay_bank_fees)", "fiVnPayBankFees", false);
                    smis.add("sum(fi_vnpay_bank_card_fees)", "fiVnPayBankCardFees", false);
                    smis.add("sum(fi_vnpay_rcgcag_pc_fees)", "fiVnPayRcgCardPcFees", false);
                    smis.add("sum(fi_vnpay_rcgcag_zing_fees)", "fiVnPayRcgCardZingFees", false);
                    smis.add("sum(fi_dapay_zfbyhk_fees)", "fiDaPayZfbYhkFees", false);
                    smis.add("sum(fi_dapay_netgate_fees)", "fiDaPayNetGateFees", false);
                    smis.add("sum(fi_dapay_bank2bank_fees)", "fiDaPayBank2BankFees", false);
                    smis.add("sum(fi_h1pay_union_pay_fees)", "fiH1PayUnionPayFees", false);
                    smis.add("sum(fi_youktpay_bank2bank_fees)", "fiYouKtPayBank2BankFees", false);
                    smis.add("sum(fx_vnpay_fees)", "fxVnPayFees", false);
                    smis.add("sum(fx_dapay_fees)", "fxDaPayFees", false);
                    smis.add("sum(op_balance)", "opBalance", false);
                    smis.add("sum(last_balance)", "lastBalance", false);
                });

        jlw
                .leftJoin(SysMerchantInfo.class, SysMerchantInfo::getId, SysMerchantIncomeStatistics::getMerchantId)
                .eq(currency != null, SysMerchantInfo::getCurrency, currency)
                .end();

        resp.setData(sysMerchantIncomeStatisticsMapper.joinSelectList(jlw, DailBalanceEntity.class));

        //填充totals数据
        for (DailBalanceEntity balance : resp.getData()) {
            if (!ObjectUtils.isEmpty(balance.getFiBankBalance())) {

                resp.getTotals().setFiBankBalance(resp.getTotals().getFiBankBalance().add(balance.getFiBankBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiArPayBalance())) {

                resp.getTotals().setFiArPayBalance(resp.getTotals().getFiArPayBalance().add(balance.getFiArPayBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiTruewalletBalance())) {
                resp.getTotals().setFiTruewalletBalance(resp.getTotals().getFiTruewalletBalance().add(balance.getFiTruewalletBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFoBalance())) {

                resp.getTotals().setFoBalance(resp.getTotals().getFoBalance().add(balance.getFoBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFoBankFeeMerchant())) {

                resp.getTotals().setFoBankFeeMerchant(resp.getTotals().getFoBankFeeMerchant().add(balance.getFoBankFeeMerchant()));
            }

            if (!ObjectUtils.isEmpty(balance.getFoEightPayAutoWithdrawalBalance())) {

                resp.getTotals().setFoEightPayAutoWithdrawalBalance(resp.getTotals().getFoEightPayAutoWithdrawalBalance().add(balance.getFoEightPayAutoWithdrawalBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFoQijiPayWithdrawalBalance())) {

                resp.getTotals().setFoQijiPayWithdrawalBalance(resp.getTotals().getFoQijiPayWithdrawalBalance().add(balance.getFoQijiPayWithdrawalBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFoDaPayWithdrawalBalance())) {
                resp.getTotals().setFoDaPayWithdrawalBalance(resp.getTotals().getFoDaPayWithdrawalBalance().add(balance.getFoDaPayWithdrawalBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFoH1PayWithdrawalBalance())) {
                resp.getTotals().setFoH1PayWithdrawalBalance(resp.getTotals().getFoH1PayWithdrawalBalance().add(balance.getFoH1PayWithdrawalBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFoYouktPayWithdrawalBalance())) {
                resp.getTotals().setFoYouktPayWithdrawalBalance(resp.getTotals().getFoYouktPayWithdrawalBalance().add(balance.getFoYouktPayWithdrawalBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFxBalance())) {
                resp.getTotals().setFxBalance(resp.getTotals().getFxBalance().add(balance.getFxBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getAjDebit())) {
                resp.getTotals().setAjDebit(resp.getTotals().getAjDebit().add(balance.getAjDebit()));
            }

            if (!ObjectUtils.isEmpty(balance.getAjCredit())) {
                resp.getTotals().setAjCredit(resp.getTotals().getAjCredit().add(balance.getAjCredit()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiVnPayZaloQrBalance())) {
                resp.getTotals().setFiVnPayZaloQrBalance(resp.getTotals().getFiVnPayZaloQrBalance().add(balance.getFiVnPayZaloQrBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiVnPayMomoQrBalance())) {
                resp.getTotals().setFiVnPayMomoQrBalance(resp.getTotals().getFiVnPayMomoQrBalance().add(balance.getFiVnPayMomoQrBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiVnPayViettelQrBalance())) {
                resp.getTotals().setFiVnPayViettelQrBalance(resp.getTotals().getFiVnPayViettelQrBalance().add(balance.getFiVnPayViettelQrBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiVnPayViettelFixBalance())) {
                resp.getTotals().setFiVnPayViettelFixBalance(resp.getTotals().getFiVnPayViettelFixBalance().add(balance.getFiVnPayViettelFixBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiVnPayBankQrBalance())) {
                resp.getTotals().setFiVnPayBankQrBalance(resp.getTotals().getFiVnPayBankQrBalance().add(balance.getFiVnPayBankQrBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiVnPayBankBalance())) {
                resp.getTotals().setFiVnPayBankBalance(resp.getTotals().getFiVnPayBankBalance().add(balance.getFiVnPayBankBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiVnPayBankCardBalance())) {
                resp.getTotals().setFiVnPayBankCardBalance(resp.getTotals().getFiVnPayBankCardBalance().add(balance.getFiVnPayBankCardBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiVnPayRcgCardPcBalance())) {
                resp.getTotals().setFiVnPayRcgCardPcBalance(resp.getTotals().getFiVnPayRcgCardPcBalance().add(balance.getFiVnPayRcgCardPcBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiVnPayRcgCardZingBalance())) {
                resp.getTotals().setFiVnPayRcgCardZingBalance(resp.getTotals().getFiVnPayRcgCardZingBalance().add(balance.getFiVnPayRcgCardZingBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiDaPayZfbYhkBalance())) {
                resp.getTotals().setFiDaPayZfbYhkBalance(resp.getTotals().getFiDaPayZfbYhkBalance().add(balance.getFiDaPayZfbYhkBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiDaPayNetGateBalance())) {
                resp.getTotals().setFiDaPayNetGateBalance(resp.getTotals().getFiDaPayNetGateBalance().add(balance.getFiDaPayNetGateBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiDaPayBank2BankBalance())) {
                resp.getTotals().setFiDaPayBank2BankBalance(resp.getTotals().getFiDaPayBank2BankBalance().add(balance.getFiDaPayBank2BankBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiH1PayUnionPayBalance())) {
                resp.getTotals().setFiH1PayUnionPayBalance(resp.getTotals().getFiH1PayUnionPayBalance().add(balance.getFiH1PayUnionPayBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFiYouKtPayBank2BankBalance())) {
                resp.getTotals().setFiYouKtPayBank2BankBalance(resp.getTotals().getFiYouKtPayBank2BankBalance().add(balance.getFiYouKtPayBank2BankBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFxDaPayBalance())) {
                resp.getTotals().setFxDaPayBalance(resp.getTotals().getFxDaPayBalance().add(balance.getFxDaPayBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFxVnPayBalance())) {
                resp.getTotals().setFxVnPayBalance(resp.getTotals().getFxVnPayBalance().add(balance.getFxVnPayBalance()));
            }

            if (!ObjectUtils.isEmpty(balance.getFxH1PayBalance())) {
                resp.getTotals().setFxH1PayBalance(resp.getTotals().getFxH1PayBalance().add(balance.getFxH1PayBalance()));
            }
        }

        return resp;
    }

    @Override
    public void downloadDailyBalance(Integer year, Integer month, String currency, List<Long> merchantId, HttpServletResponse response) {
        DailBalanceSearchResp resp = this.searchDailyBalance(year, month, currency, merchantId);

        //创建汇出表的文件名
        String fileName = "Merchant_Daily_Balance_" + year + "_" + month;

        try {
            ExportParams params = new ExportParams();
            params.setSheetName("Worksheet");
            //尝试导出表
            ExcelUtils.exportExcel(resp.getData(), DailBalanceEntity.class, fileName, params, response);
        } catch (IOException e) {
            e.printStackTrace();
            log.error(fileName + ".xlsx 表导出失败");
        }
    }

}